import React from 'react';
void React;
import styles from './index.module.less';

const THEME_STORAGE_KEY = 'theme';

type ThemeMode = 'light' | 'dark';

type MediaQueryListWithOldApi = MediaQueryList & {
  addListener: (
    listener: (this: MediaQueryList, ev: MediaQueryListEvent) => void
  ) => void;
  removeListener: (
    listener: (this: MediaQueryList, ev: MediaQueryListEvent) => void
  ) => void;
};

function getSystemTheme(): ThemeMode {
  if (typeof window === 'undefined' || !window.matchMedia) return 'light';
  return window.matchMedia('(prefers-color-scheme: dark)').matches
    ? 'dark'
    : 'light';
}

function applyTheme(theme: ThemeMode) {
  if (typeof document === 'undefined') return;
  document.documentElement.setAttribute('data-theme', theme);
}

const ThemeToggle = () => {
  const [theme, setTheme] = React.useState<ThemeMode>(() => {
    try {
      const saved = localStorage.getItem(THEME_STORAGE_KEY) as ThemeMode | null;
      return saved ?? getSystemTheme();
    } catch {
      return getSystemTheme();
    }
  });

  let initialHasChoice = false;
  try {
    initialHasChoice = localStorage.getItem(THEME_STORAGE_KEY) !== null;
  } catch {
    initialHasChoice = false;
  }
  const userHasChoiceRef = React.useRef<boolean>(initialHasChoice);

  React.useEffect(() => {
    applyTheme(theme);
    try {
      localStorage.setItem(THEME_STORAGE_KEY, theme);
    } catch {
      // ignore storage errors
    }
  }, [theme]);

  React.useEffect(() => {
    if (typeof window === 'undefined' || !window.matchMedia) return;
    const mql = window.matchMedia('(prefers-color-scheme: dark)');

    const handleChange = () => {
      if (!userHasChoiceRef.current) {
        setTheme(mql.matches ? 'dark' : 'light');
      }
    };

    const legacyHandler = (e: MediaQueryListEvent) => {
      if (!userHasChoiceRef.current) {
        setTheme(e.matches ? 'dark' : 'light');
      }
    };

    if (!userHasChoiceRef.current) {
      handleChange();
    }

    if (typeof mql.addEventListener === 'function') {
      mql.addEventListener('change', handleChange);
    } else if ('addListener' in mql) {
      (mql as MediaQueryListWithOldApi).addListener(legacyHandler);
    }

    return () => {
      if (typeof mql.removeEventListener === 'function') {
        mql.removeEventListener('change', handleChange);
      } else if ('removeListener' in mql) {
        (mql as MediaQueryListWithOldApi).removeListener(legacyHandler);
      }
    };
  }, []);

  const onToggle = (e: React.ChangeEvent<HTMLInputElement>) => {
    userHasChoiceRef.current = true;
    setTheme(e.target.checked ? 'dark' : 'light');
  };

  const checked = theme === 'dark';

  return (
    <div className={styles.container}>
      <label className={styles.switch}>
        <input
          className={styles.switch__input}
          type="checkbox"
          role="switch"
          checked={checked}
          onChange={onToggle}
          aria-checked={checked}
          aria-label="Toggle theme"
        />
        <span className={styles.switch__base_outer} />
        <span className={styles.switch__base_inner} />
        <svg
          className={styles.switch__base_neon}
          viewBox="0 0 40 24"
          width="40px"
          height="24px"
        >
          <defs>
            <filter id="switch-glow">
              <feGaussianBlur result="coloredBlur" stdDeviation={1} />
              <feMerge>
                <feMergeNode in="coloredBlur" />
                <feMergeNode in="SourceGraphic" />
              </feMerge>
            </filter>
            <linearGradient id="switch-gradient1" x1={0} y1={0} x2={1} y2={0}>
              <stop offset="0%" stopColor="var(--color-primary)" />
              <stop offset="100%" stopColor="var(--color-primary-hover)" />
            </linearGradient>
            <linearGradient
              id="switch-gradient2"
              x1="0.7"
              y1={0}
              x2="0.3"
              y2={1}
            >
              <stop
                offset="25%"
                stopColor="var(--color-primary)"
                stopOpacity={0}
              />
              <stop
                offset="50%"
                stopColor="var(--color-primary)"
                stopOpacity={0.3}
              />
              <stop
                offset="100%"
                stopColor="var(--color-primary-hover)"
                stopOpacity={0.3}
              />
            </linearGradient>
          </defs>
          <path
            fill="none"
            filter="url(#switch-glow)"
            stroke="url(#switch-gradient1)"
            strokeWidth={1}
            strokeDasharray="0 104.26 0"
            strokeDashoffset="0.01"
            strokeLinecap="round"
            d="m.5,12C.5,5.649,5.649.5,12,.5h16c6.351,0,11.5,5.149,11.5,11.5s-5.149,11.5-11.5,11.5H12C5.649,23.5.5,18.351.5,12Z"
          />
        </svg>
        <span className={styles.switch__knob_shadow} />
        <span className={styles.switch__knob_container}>
          <span className={styles.switch__knob}>
            <svg
              className={styles.switch__knob_neon}
              viewBox="0 0 48 48"
              width="48px"
              height="48px"
            >
              <circle
                fill="none"
                stroke="url(#switch-gradient2)"
                strokeDasharray="0 90.32 0 54.19"
                strokeLinecap="round"
                strokeWidth={1}
                r={23}
                cx={24}
                cy={24}
                transform="rotate(-112.5,24,24)"
              />
            </svg>
          </span>
        </span>
        <span className={styles.switch__led} />
        <span className={styles.switch__text}>Power</span>
      </label>
    </div>
  );
};
export default ThemeToggle;
